home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / Libraries / BlobMgr / Demo Folder / Peg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-21  |  14.2 KB  |  736 lines  |  [TEXT/KAHL]

  1. /*
  2.  * Blob Manager Demonstration:  Peg Solitaire module
  3.  *
  4.  * 31 July 1986        Paul DuBois
  5.  *
  6.  * 23 Dec 93
  7.  * - Made window a little wider so title in title bar doesn't get chopped.
  8.  * 24 Dec 93
  9.  * - Use RGB gray in final board positions rather than dithered gray when possible.
  10.  * This uses something of a trick in that drawing such positions uses the functions
  11.  * BeginBlobDimDraw() and EndBlobDimDraw() that are normally intended for use in
  12.  * drawing dim blobs.  But the final positions are active, not disabled, so
  13.  * they're not really dim.
  14.  */
  15.  
  16. # include    "TransSkel.h"
  17.  
  18. # include    "BlobMgr.h"
  19. # include    "BlobDemo.h"
  20.  
  21.  
  22. # define    rows        7        /* number of rows on board */
  23. # define    columns        7        /* number of columns on board */
  24. # define    pieceSize    20        /* size of each piece */
  25. # define    vMessage    141        /* vertical position of message */
  26.  
  27. /*
  28.  * bits used in configuration information
  29.  *
  30.  * bit 0    0 board position unused
  31.  *        1 board position used
  32.  * bit 1    0 position does not have marble at start
  33.  *        1 position has marble at start
  34.  * bit 2    0 position does not have marble at end
  35.  *        1 position has marble at end
  36.  *
  37.  * bits 1 and 2 are irrelevant unless bit 0 is on
  38.  */
  39.  
  40. # define    posUsedMask    1
  41. # define    inStartMask    2
  42. # define    inFinalMask    4
  43.  
  44.  
  45. static WindowPtr    wind;
  46. static MenuHandle    cnfgMenu;
  47.  
  48.  
  49. static BlobSetHandle    boardBlobs = nil;        /* receptors */
  50. static BlobHandle        board[columns][rows];
  51.  
  52. static short            hMid;
  53. static short            cnfgNo;        /* current configuration */
  54. static short            moves;        /* number of moves left */
  55. static Boolean            pause;
  56. static Str255            statusStr = "\p";
  57.  
  58.  
  59. typedef struct
  60. {
  61.     unsigned char    *lName;                    /* name of configuration */
  62.     char    lCnfg[columns][rows];    /* board positions */
  63. } Layout;
  64.  
  65.  
  66. static Layout centerToCenter =
  67. {
  68.     "\pCenter To Center",
  69.     {
  70.         { 0, 0, 3, 3, 3, 0, 0 },
  71.         { 0, 0, 3, 3, 3, 0, 0 },
  72.         { 3, 3, 3, 3, 3, 3, 3 },
  73.         { 3, 3, 3, 5, 3, 3, 3 },
  74.         { 3, 3, 3, 3, 3, 3, 3 },
  75.         { 0, 0, 3, 3, 3, 0, 0 },
  76.         { 0, 0, 3, 3, 3, 0, 0 }
  77.     }
  78. };
  79.  
  80.  
  81. static Layout cornerToCorner =
  82. {
  83.     "\pCorner To Corner",
  84.     {
  85.         { 0, 0, 1, 3, 3, 0, 0 },
  86.         { 0, 3, 3, 3, 3, 3, 0 },
  87.         { 3, 3, 3, 3, 3, 3, 3 },
  88.         { 3, 3, 3, 3, 3, 3, 3 },
  89.         { 3, 3, 3, 3, 3, 3, 3 },
  90.         { 0, 3, 3, 3, 3, 3, 0 },
  91.         { 0, 0, 3, 3, 7, 0, 0 }
  92.     }
  93. };
  94.  
  95.  
  96. static Layout doubleCross =
  97. {
  98.     "\pDouble Cross",
  99.     {
  100.         { 0, 0, 1, 3, 1, 0, 0 },
  101.         { 0, 3, 1, 3, 1, 3, 0 },
  102.         { 1, 1, 3, 3, 3, 1, 1 },
  103.         { 3, 3, 3, 7, 3, 3, 3 },
  104.         { 1, 1, 3, 3, 3, 1, 1 },
  105.         { 0, 3, 1, 3, 1, 3, 0 },
  106.         { 0, 0, 1, 3, 1, 0, 0 }
  107.     }
  108. };
  109.  
  110.  
  111. static Layout finalScore =
  112. {
  113.     "\pFinal Score",
  114.     {
  115.         { 0, 0, 7, 7, 7, 0, 0 },
  116.         { 0, 7, 3, 3, 3, 7, 0 },
  117.         { 7, 3, 7, 3, 7, 3, 7 },
  118.         { 7, 3, 3, 5, 3, 3, 7 },
  119.         { 7, 3, 3, 3, 3, 3, 7 },
  120.         { 0, 7, 3, 7, 3, 7, 0 },
  121.         { 0, 0, 7, 7, 7, 0, 0 }
  122.     }
  123. };
  124.  
  125.  
  126. static Layout fiveCrosses =
  127. {
  128.     "\pFive Crosses",
  129.     {
  130.         { 0, 0, 1, 3, 1, 0, 0 },
  131.         { 0, 1, 3, 3, 3, 1, 0 },
  132.         { 1, 3, 1, 3, 1, 3, 1 },
  133.         { 3, 3, 3, 7, 3, 3, 3 },
  134.         { 1, 3, 1, 3, 1, 3, 1 },
  135.         { 0, 1, 3, 3, 3, 1, 0 },
  136.         { 0, 0, 1, 3, 1, 0, 0 }
  137.     }
  138. };
  139.  
  140.  
  141. static Layout footballTeam =
  142. {
  143.     "\pFootball Team",
  144.     {
  145.         { 0, 0, 3, 3, 3, 0, 0 },
  146.         { 0, 0, 3, 3, 3, 0, 0 },
  147.         { 1, 1, 3, 3, 3, 1, 1 },
  148.         { 1, 1, 3, 5, 3, 1, 1 },
  149.         { 1, 1, 1, 1, 1, 1, 1 },
  150.         { 0, 0, 1, 1, 1, 0, 0 },
  151.         { 0, 0, 1, 1, 1, 0, 0 }
  152.     }
  153. };
  154.  
  155.  
  156. static Layout greekCross =
  157. {
  158.     "\pGreek Cross",
  159.     {
  160.         { 0, 0, 1, 1, 1, 0, 0 },
  161.         { 0, 0, 1, 3, 1, 0, 0 },
  162.         { 1, 1, 1, 3, 1, 1, 1 },
  163.         { 1, 3, 3, 7, 3, 3, 1 },
  164.         { 1, 1, 1, 3, 1, 1, 1 },
  165.         { 0, 0, 1, 3, 1, 0, 0 },
  166.         { 0, 0, 1, 1, 1, 0, 0 }
  167.     }
  168. };
  169.  
  170.  
  171. static Layout latinCross =
  172. {
  173.     "\pLatin Cross",
  174.     {
  175.         { 0, 0, 1, 1, 1, 0, 0 },
  176.         { 0, 0, 1, 3, 1, 0, 0 },
  177.         { 1, 1, 3, 3, 3, 1, 1 },
  178.         { 1, 1, 1, 7, 1, 1, 1 },
  179.         { 1, 1, 1, 3, 1, 1, 1 },
  180.         { 0, 0, 1, 1, 1, 0, 0 },
  181.         { 0, 0, 1, 1, 1, 0, 0 },
  182.     }
  183. };
  184.  
  185.  
  186. static Layout leTricolet =
  187. {
  188.     "\pLe Tricolet",
  189.     {
  190.         { 0, 0, 7, 3, 7, 0, 0 },
  191.         { 0, 3, 3, 7, 3, 3, 0 },
  192.         { 7, 3, 3, 7, 3, 3, 7 },
  193.         { 3, 7, 7, 1, 7, 7, 3 },
  194.         { 7, 3, 3, 7, 3, 3, 7 },
  195.         { 0, 3, 3, 7, 3, 3, 0 },
  196.         { 0, 0, 7, 3, 7, 0, 0 }
  197.     }
  198. };
  199.  
  200.  
  201. static Layout lonelyCross =
  202. {
  203.     "\pLonely Cross",
  204.     {
  205.         { 0, 0, 7, 7, 7, 0, 0 },
  206.         { 0, 7, 3, 3, 3, 7, 0 },
  207.         { 7, 3, 3, 7, 3, 3, 7 },
  208.         { 7, 3, 7, 5, 7, 3, 7 },
  209.         { 7, 3, 3, 7, 3, 3, 7 },
  210.         { 0, 7, 3, 3, 3, 7, 0 },
  211.         { 0, 0, 7, 7, 7, 0, 0 }
  212.     }
  213. };
  214.  
  215.  
  216. static Layout octagon =
  217. {
  218.     "\pOctagon",
  219.     {
  220.         { 0, 0, 1, 3, 1, 0, 0 },
  221.         { 0, 3, 3, 3, 3, 3, 0 },
  222.         { 1, 3, 3, 3, 3, 3, 1 },
  223.         { 3, 3, 3, 7, 3, 3, 3 },
  224.         { 1, 3, 3, 3, 3, 3, 1 },
  225.         { 0, 3, 3, 3, 3, 3, 0 },
  226.         { 0, 0, 1, 3, 1, 0, 0 }
  227.     }
  228. };
  229.  
  230.  
  231. static Layout pentagon =
  232. {
  233.     "\pPentagon",
  234.     {
  235.         { 0, 0, 1, 3, 1, 0, 0 },
  236.         { 0, 0, 3, 3, 3, 0, 0 },
  237.         { 1, 3, 3, 3, 3, 3, 1 },
  238.         { 3, 3, 3, 7, 3, 3, 3 },
  239.         { 1, 3, 3, 3, 3, 3, 1 },
  240.         { 0, 0, 3, 3, 3, 0, 0 },
  241.         { 0, 0, 1, 1, 1, 0, 0 }
  242.     }
  243. };
  244.  
  245.  
  246. static Layout pyramidChefren =
  247. {
  248.     "\pPyramid of Chefren",
  249.     {
  250.         { 0, 0, 1, 1, 1, 0, 0 },
  251.         { 0, 1, 1, 1, 1, 1, 0 },
  252.         { 1, 1, 1, 3, 1, 1, 1 },
  253.         { 1, 1, 3, 7, 3, 1, 1 },
  254.         { 1, 3, 3, 3, 3, 3, 1 },
  255.         { 0, 1, 1, 1, 1, 1, 0 },
  256.         { 0, 0, 1, 1, 1, 0, 0 },
  257.     }
  258. };
  259.  
  260.  
  261. static Layout pyramidCheops =
  262. {
  263.     "\pPyramid of Cheops",
  264.     {
  265.         { 0, 0, 1, 1, 1, 0, 0 },
  266.         { 0, 1, 1, 3, 1, 1, 0 },
  267.         { 1, 1, 3, 3, 3, 1, 1 },
  268.         { 1, 3, 3, 7, 3, 3, 1 },
  269.         { 3, 3, 3, 3, 3, 3, 3 },
  270.         { 0, 1, 1, 1, 1, 1, 0 },
  271.         { 0, 0, 1, 1, 1, 0, 0 },
  272.     }
  273. };
  274.  
  275.  
  276. static Layout shrine =
  277. {
  278.     "\pShrine",
  279.     {
  280.         { 0, 0, 1, 3, 1, 0, 0 },
  281.         { 0, 1, 1, 3, 1, 1, 0 },
  282.         { 1, 3, 3, 7, 3, 3, 1 },
  283.         { 1, 1, 1, 3, 1, 1, 1 },
  284.         { 1, 1, 1, 3, 1, 1, 1 },
  285.         { 0, 1, 3, 3, 3, 1, 0 },
  286.         { 0, 0, 3, 3, 3, 0, 0 },
  287.     }
  288. };
  289.  
  290.  
  291. static Layout tiffanyLamp =
  292. {
  293.     "\pTiffany Lamp",
  294.     {
  295.         { 0, 0, 1, 3, 1, 0, 0 },
  296.         { 0, 0, 3, 3, 3, 0, 0 },
  297.         { 1, 3, 3, 3, 3, 3, 1 },
  298.         { 1, 1, 1, 7, 1, 1, 1 },
  299.         { 1, 1, 1, 3, 1, 1, 1 },
  300.         { 0, 0, 3, 3, 3, 0, 0 },
  301.         { 0, 0, 3, 3, 3, 0, 0 },
  302.     }
  303. };
  304.  
  305.  
  306. static Layout tiltedSquare =
  307. {
  308.     "\pTilted Square",
  309.     {
  310.         { 0, 0, 1, 3, 1, 0, 0 },
  311.         { 0, 0, 3, 3, 3, 0, 0 },
  312.         { 1, 3, 3, 3, 3, 3, 1 },
  313.         { 3, 3, 3, 5, 3, 3, 3 },
  314.         { 1, 3, 3, 3, 3, 3, 1 },
  315.         { 0, 0, 3, 3, 3, 0, 0 },
  316.         { 0, 0, 1, 3, 1, 0, 0 }
  317.     }
  318. };
  319.  
  320.  
  321. static Layout nullLayout =
  322. {
  323.     nil
  324. };
  325.  
  326.  
  327. static Layout    *configurations [] =
  328. {
  329.     ¢erToCenter,
  330.     &cornerToCorner,
  331.     &doubleCross,
  332.     &finalScore,
  333.     &fiveCrosses,
  334.     &footballTeam,
  335.     &greekCross,
  336.     &latinCross,
  337.     &leTricolet,
  338.     &lonelyCross,
  339.     &octagon,
  340.     &pentagon,
  341.     &pyramidChefren,
  342.     &pyramidCheops,
  343.     &shrine,
  344.     &tiffanyLamp,
  345.     &tiltedSquare,
  346.     &nullLayout
  347. };
  348.  
  349.  
  350. static void
  351. StatusMesg (StringPtr s)
  352. {
  353. Rect    r;
  354.  
  355.     SetRect (&r, 0, vMessage, wind->portRect.right, vMessage + 12);
  356.     TextBox    (s+1, (long) s[0], &r, teJustCenter);
  357.     StrCpy (statusStr, s);
  358. }
  359.  
  360.  
  361. /*
  362.  * Board position drawing procedure.  This draws a blank for those
  363.  * positions that are unused.  For used positions, the blob is filled
  364.  * with light gray if a peg should be in the position at the end of
  365.  * play.  In the drag region, a hole is drawn if there is no glob,
  366.  * otherwise a peg is drawn.  It does not matter what glob is attached,
  367.  * only whether there is one.
  368.  *
  369.  * partCode is ignored - always draw entire blob.
  370.  */
  371.  
  372. static pascal void
  373. DrawBoardPos (BlobHandle bDst, BlobHandle bSrc, short partCode)
  374. {
  375. short    blobType;
  376. Rect    r;
  377.  
  378.     blobType = GetBRefCon (bDst);    /* indicates unused, used and present
  379.                                         in final, or used and not present
  380.                                         in final */
  381.     r = BStatBox (bDst);            /* blob outline */
  382.     EraseRect (&r);
  383.     if (blobType & posUsedMask)
  384.     {
  385.         if (blobType & inFinalMask)
  386.         {
  387.             BeginBlobDimDraw (bDst, partCode);
  388.             PaintRect (&r);
  389.             EndBlobDimDraw ();
  390.         }
  391.         if (BGlob (bDst) == nil)    /* no peg, just draw hole */
  392.         {
  393.             InsetRect (&r, 7, 7);
  394.             PaintOval (&r);
  395.         }
  396.         else
  397.         {
  398.             InsetRect (&r, 2, 2);    /* draw peg */
  399.             EraseOval (&r);
  400.             PenSize (2, 2);
  401.             FrameOval (&r);
  402.             PenNormal ();
  403.         }
  404.     }
  405. }
  406.  
  407.  
  408. /*
  409.  * Build the board.  All positions are initially given a reference
  410.  * value of 0, meaning an unused position.  This means that the board
  411.  * is blank until a configuration is set up.  The blobs are built by
  412.  * contructing the static and drag regions, without drawing anything,
  413.  * since they are drawn by procedure.
  414.  */
  415.  
  416. static void
  417. InitBoard (void)
  418. {
  419. short        h, v;
  420. Rect        r, r2;
  421. BlobHandle    b;
  422.  
  423.     boardBlobs = NewBlobSet ();
  424.     for (v = 0; v < rows; v++)
  425.     {
  426.         for (h = 0; h < columns; h++)
  427.         {
  428.             b = NewBlob (boardBlobs, true, infiniteGlue, true, (long) 0);
  429.             board[h][v] = b;
  430.             SetRect (&r, 0, 0, pieceSize, pieceSize);
  431.             OffsetRect (&r, h * pieceSize + 5, v * pieceSize);
  432.             r2 = r;
  433.             InsetRect (&r2, 2, 2);
  434.             SetProcRectBlob (b, DrawBoardPos, &r2, &r);
  435.             SetBlobFlags (b, bProcManualDimMask);
  436.         }
  437.     }
  438. }
  439.  
  440.  
  441. /*
  442.  * Set the board to a given configuration.  The first board blob is
  443.  * used as the general glob and as the match for final positions.
  444.  */
  445.  
  446. static void
  447. SetupBoard (Layout *layout)
  448. {
  449. short        h, v, val;
  450. short        startCount = 0;
  451. short        finalCount = 0;
  452. BlobHandle    b;
  453. Str255        s;
  454.  
  455.     DisableBlobSet (boardBlobs);    /* turn off drawing temporarily */
  456.     for (v = 0; v < rows; v++)
  457.     {
  458.         for (h = 0; h < columns; h++)
  459.         {
  460.             b = board[h][v];
  461.             val = (short) layout->lCnfg[v][h];
  462.             SetBRefCon (b, val);
  463.             UnglueGlob (b);                /* clear any glob and match set */
  464.             DisposeBlobMatchSet (b);    /* from previous configuration */
  465.             if (val & posUsedMask)        /* check that position is used */
  466.             {
  467.                 if (val & inStartMask)    /* position has marble at start */
  468.                 {
  469.                     startCount++;
  470.                     GlueGlob (FirstBlob (boardBlobs), b);
  471.                 }
  472.                 if (val & inFinalMask)    /* position has marble at end */
  473.                 {
  474.                     finalCount++;
  475.                     NewBlobMatch (FirstBlob (boardBlobs), b);
  476.                 }
  477.             }
  478.         }
  479.     }
  480.  
  481.     ShowBlobSet (boardBlobs);
  482.     moves = startCount - finalCount;
  483.     MovesLeft (moves, s);
  484.     StatusMesg (s);
  485.     pause = false;
  486. }
  487.  
  488.  
  489. static void
  490. Pause (StringPtr msg)
  491. {
  492.     StatusMesg (msg);
  493.     pause = true;
  494. }
  495.  
  496.  
  497. /*
  498.  * Check whether a board position is empty.  The coordinates must be
  499.  * legal, the position must be used in the current configuration,
  500.  * and the position must have a marble in it.
  501.  */
  502.  
  503. static Boolean
  504. BoardPosEmpty (short h, short v)
  505. {
  506.     return (h >= 0 && h < columns && v >= 0 && v < rows
  507.             && (GetBRefCon (board[h][v]) & posUsedMask)
  508.             && BGlob (board[h][v]) == nil);
  509. }
  510.  
  511.  
  512. static Boolean
  513. BoardPosFilled (short h, short v)
  514. {
  515.     return (h >= 0 && h < columns && v >= 0 && v < rows
  516.             && (GetBRefCon (board[h][v]) & posUsedMask)
  517.             && BGlob (board[h][v]) != nil);
  518. }
  519.  
  520.  
  521. /*
  522.  * Test whether a piece can move or not
  523.  */
  524.  
  525. static Boolean
  526. CanMove (short h, short v)
  527. {
  528.     return ((BoardPosEmpty (h - 2, v) && BoardPosFilled (h - 1, v))
  529.             || (BoardPosEmpty (h + 2, v) && BoardPosFilled (h + 1, v))
  530.             || (BoardPosEmpty (h, v - 2) && BoardPosFilled (h, v - 1))
  531.             || (BoardPosEmpty (h, v + 2) && BoardPosFilled (h, v + 1)));
  532. }
  533.  
  534.  
  535. /*
  536.  * See if any more moves can be made.  True if stalemated.
  537.  */
  538.  
  539. static Boolean
  540. HaveStaleMate (void)
  541. {
  542. BlobHandle    b;
  543. short        h, v;
  544.  
  545.     for (v = 0; v < rows; v++)
  546.     {
  547.         for (h = 0; h < columns; h++)
  548.         {
  549.             b = board[h][v];
  550.             if (GetBRefCon (b) & posUsedMask)
  551.             {
  552.                 if (BGlob (b) != nil && CanMove (h, v))
  553.                     return (false);        /* at least 1 move can be made */
  554.             }
  555.         }
  556.     }
  557.     return (true);
  558. }
  559.  
  560.  
  561. /*
  562.  * Given a blob handle, find the board position that corresponds to it.
  563.  * This is used to map hits in the blob set (a list) to the position in
  564.  * the board (a 2-d array).
  565.  */
  566.  
  567. static void
  568. FindBoardPos (BlobHandle b, short *h, short *v)
  569. {
  570. short    i, j;
  571.  
  572.     for (i = 0; i < columns; ++i)
  573.     {
  574.         for (j = 0; j < rows; ++j)
  575.         {
  576.             if (board[i][j] == b)
  577.             {
  578.                 *h = i;
  579.                 *v = j;
  580.                 return;
  581.             }
  582.         }
  583.     }
  584.     /* shouldn't ever get here */
  585. }
  586.  
  587.  
  588.  
  589. /*
  590.  * When a piece is clicked on, the advisory checks whether the piece has
  591.  * any legal moves available to it.  If so, it returns true, so that
  592.  * BlobClick is allowed to drag the piece.  After the piece has been
  593.  * dragged, the advisory checks whether the position it was dragged to
  594.  * is legal.  If it is, the piece that was jumped is removed from the
  595.  * board, and true is returned, so that BlobClick will complete the
  596.  * tranfer of the dragged piece to its new position.
  597.  *
  598.  * Messages passed to the advisory follow the pattern
  599.  *
  600.  * { { advRClick advRClick* } advXfer* }*
  601.  *
  602.  * where * means 0 or more instances of the thing *'ed.  In particular,
  603.  * the advXfer message is never seen without a preceding advRClick.
  604.  */
  605.  
  606. static pascal Boolean
  607. Advisory (short mesg, BlobHandle b)
  608. {
  609. static short    h, v;    /* static to save board position of click on piece */
  610. short            h2, v2;
  611.  
  612.     switch (mesg)
  613.     {
  614.  
  615.     case advRClick:    /* first click on piece */
  616.  
  617.         FindBoardPos (b, &h, &v);    /* find where it is */
  618.         return (CanMove (h, v));
  619.  
  620.     case advXfer:    /* Mouse released after dragging piece */
  621.  
  622.         FindBoardPos (b, &h2, &v2);
  623.         if ( (       (h2 == h - 2 && v2 == v)
  624.                 || (h2 == h + 2 && v2 == v)
  625.                 || (h2 == h && v2 == v - 2)
  626.                 || (h2 == h && v2 == v + 2)  )
  627.             && BoardPosFilled ((h + h2) / 2, (v + v2) / 2))
  628.         {
  629.             UnglueGlob (board[(h + h2) / 2][(v + v2) / 2]);
  630.             return (true);
  631.         }
  632.         return (false);
  633.  
  634.     }
  635. }
  636.  
  637.  
  638. static pascal void
  639. DoConfiguration (short item)
  640. {
  641.     CheckItem (cnfgMenu, cnfgNo + 1, false);
  642.     SetupBoard (configurations [cnfgNo = item-1]);
  643.     CheckItem (cnfgMenu, cnfgNo + 1, true);
  644. }
  645.  
  646.  
  647. static pascal void
  648. Mouse (Point pt, long t, short mods)
  649. {
  650. Str255        s;
  651. short        i;
  652.  
  653.  
  654.     if (!pause)
  655.     {
  656.         BlobClick (pt, t, nil, boardBlobs);
  657.         if (BClickResult () == bcXfer)
  658.         {
  659.             --moves;
  660.             if (BlobSetQuiet (boardBlobs))
  661.                 Pause ("\pYou Win");
  662.             else if (moves == 0)
  663.                 Pause ("\pYou Lose");
  664.             else if (HaveStaleMate ())
  665.                 Pause ("\pYou Can't Move");
  666.             else
  667.             {
  668.                 MovesLeft (moves, s);
  669.                 StatusMesg (s);
  670.             }
  671.         }
  672.     }
  673. }
  674.  
  675.  
  676. static pascal void
  677. Update (Boolean resized)
  678. {
  679.     DrawBlobSet (boardBlobs);
  680.     StatusMesg (statusStr);
  681. }
  682.  
  683.  
  684. static pascal void
  685. Activate (Boolean active)
  686. {
  687. Layout    *l;
  688.  
  689.     if (active)
  690.     {
  691.         SetDragRects (wind);
  692.         SetBCPermissions (false, true, false, false, false);    /* xfer only */
  693.         SetBCAdvisory (Advisory);
  694.         cnfgMenu = GetMenu (pegCnfgMenuRes);
  695.         for (l = configurations[0]; l->lName != nil; ++l)
  696.         {
  697.             AppendMenu (cnfgMenu, l->lName);
  698.         }
  699.         SkelMenu (cnfgMenu, DoConfiguration, DoMClobber, false, true);
  700.         CheckItem (cnfgMenu, cnfgNo+1, true);
  701.     }
  702.     else
  703.     {
  704.         SkelRmveMenu (cnfgMenu);
  705.         SetBCAdvisory (nil);
  706.     }
  707. }
  708.  
  709.  
  710. void
  711. PegInit (void)
  712. {
  713. Rect    r;
  714.  
  715.     SkelWindow (wind = GetDemoWind (pegWindRes),
  716.                 Mouse,            /* mouse clicks */
  717.                 nil,            /* key clicks */
  718.                 Update,            /* updates */
  719.                 Activate,        /* activate/deactivate events */
  720.                 nil,            /* close window */
  721.                 DoWClobber,        /* dispose of window */
  722.                 nil,            /* idle proc */
  723.                 false);            /* irrelevant, since no idle proc */
  724.  
  725.     hMid = wind->portRect.right / 2;
  726.  
  727.     /*
  728.      * Make blobs and set initial configuration to the Latin Cross, which
  729.      * is good for learning some of the problems of peg solitaire.
  730.      */
  731.     InitBoard ();
  732.     SetupBoard (configurations[cnfgNo = 7]);
  733.  
  734.     MakeFrontWind (wind);
  735. }
  736.